package docker

import (
	aiohttp "blockchains-aio/http"
	"fmt"
	"github.com/gin-gonic/gin"
	"io"
	"log"
	"net"
	"net/http"
	"net/http/httputil"
)

func WithHttpReverseUnixSocketProxy(unixPath string, host string, schema string, uri string, query string, ctx *gin.Context) error {
	schema = "http"
	conn, err := net.Dial("unix", unixPath)
	host = "localhost"

	if err != nil {
		return fmt.Errorf("Internal Server Error: dial %s %w", unixPath, err)
	}

	log.Println("Unix start")

	c := httputil.NewClientConn(conn, nil)
	defer c.Close()

	request := aiohttp.BuildRequest(ctx, host, schema, uri, query)
	request.Response.Header.Set("Transfer-Encoding", "chunked")

	res, err := c.Do(request)
	if err != nil {
		return fmt.Errorf("Proxy Do Error:%w", err)
	}
	defer res.Body.Close()

	if _, err := io.Copy(ctx.Writer, res.Body); err != nil {
		return fmt.Errorf("Ouput body Error:%w", err)
	}

	return nil
}

func UnixSocketProxy(unixPath string, host string, schema string, uri string, query string, ctx *gin.Context) error {
	schema = "http"
	conn, err := net.Dial("unix", unixPath)
	host = "localhost"

	if err != nil {
		return fmt.Errorf("Internal Server Error: dial %s %w", unixPath, err)
	}

	log.Println("Unix start")

	c := httputil.NewClientConn(conn, nil)
	defer c.Close()

	/*
		request := aiohttp.NewHttpRequest(host, schema, uri, query)
		log.Printf("Unix Req: host=%v uri=%v query=%v body=%d", request.Host, request.URL.RequestURI(), request.URL.RawQuery, request.ContentLength)

		if err := aiohttp.ConvertRequest(ctx, request, false); err != nil {
			return fmt.Errorf(fmt.Sprintf("cannot parse requestURI %q: %w", request.RequestURI, err))
		}

		log.Printf("Unix Http uri=%v url=%+v body=%d", request.RequestURI, request.URL, request.ContentLength)
	*/
	request := aiohttp.BuildRequest(ctx, host, schema, uri, query)

	res, err := c.Do(request)
	if err != nil {
		return fmt.Errorf("Proxy Do Error:%w", err)
	}
	defer res.Body.Close()

	//copyHeader(ctx, res.Header)
	//bodyBytes, err := io.ReadAll(res.Body)
	//log.Println("body:" + string(bodyBytes))
	if _, err := io.Copy(ctx.Writer, res.Body); err != nil {
		return fmt.Errorf("Ouput body Error:%w", err)
	}

	return nil
}

func copyHeader(ctx *gin.Context, src http.Header) {
	for k, vv := range src {
		for _, v := range vv {
			//ctx.Request.Response.Header.Add(k, v)
			res := ctx.Request.Response
			resHeader := res.Header
			resHeader.Set(k, v)
		}
	}
}
